package com.yy.wga.pay.service.client;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.yy.wga.common.core.enmus.EResponseCode;
import com.yy.wga.common.core.exception.BusinessException;
import com.yy.wga.common.util.common.JsonUtils;
import com.yy.wga.common.util.common.StringUtils;
import com.yy.wga.common.utils.date.DateUtils;
import com.yy.wga.common.utils.mapping.BeansUtils;
import com.yy.wga.pay.feign.eunms.EPayChannel;
import com.yy.wga.pay.service.client.enums.EPayOrderStatus;
import com.yy.wga.pay.service.client.request.BaseOauthTokenRequest;
import com.yy.wga.pay.service.client.request.BasePreOrderRequest;
import com.yy.wga.pay.service.client.request.BaseQueryOrderRequest;
import com.yy.wga.pay.service.client.request.BaseQueryUserInfoRequest;
import com.yy.wga.pay.service.client.request.BaseRefundRequest;
import com.yy.wga.pay.service.client.request.BaseTransferRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayAppPreOrderRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayH5PreOrderRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayOauthTokenRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayQueryOrderRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayQueryUserInfoRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayRefundRequest;
import com.yy.wga.pay.service.client.request.alipay.AliPayTransferRequest;
import com.yy.wga.pay.service.client.request.alipay.dto.AliPayTransferContentDTO;
import com.yy.wga.pay.service.client.response.BaseOauthTokenResponse;
import com.yy.wga.pay.service.client.response.BasePreOrderResponse;
import com.yy.wga.pay.service.client.response.BaseQueryOrderResponse;
import com.yy.wga.pay.service.client.response.BaseQueryUserInfoResponse;
import com.yy.wga.pay.service.client.response.BaseRefundResponse;
import com.yy.wga.pay.service.client.response.BaseTransferResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayAppPreOrderResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayH5PreOrderResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayOauthTokenResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayQueryOrderResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayQueryUserInfoResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayRefundResponse;
import com.yy.wga.pay.service.client.response.alipay.AliPayTransferResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
* Created by gc on 2021/8/30.
*
* @author : gc
*
* Description: 支付宝接口
**/
@Slf4j
@Component
public class AliPayClient implements PayClient {
    /**
     * 支付宝商户id
     */
    @Value(value = "${alipay.app.id:}")
    private String appId;
    /**
     * 支付宝商户私钥
     */
    @Value(value = "${alipay.app.privateKey:}")
    private String privateKey;
    /**
     * 商户公钥证书路径（app_cert_path 文件绝对路径）
     */
    @Value(value = "${alipay.alipay.appCertPath:}")
    private String appCertPath;
    /**
     * 支付宝公钥证书文件路径（alipay_cert_path 文件绝对路径）
     */
    @Value(value = "${alipay.alipay.publicCertPath:}")
    private String publicCertPath;
    /**
     * 支付宝CA根证书文件路径（alipay_root_cert_path 文件绝对路径）
     */
    @Value(value = "${alipay.alipay.rootCertPath:}")
    private String rootCertPath;
    /**
     * app支付订单回调地址
     */
    @Value(value = "${alipay.appPay.callbackUrl:}")
    private String appPayCallbackUrl;
    /**
     * 用户付款中途退出返回商户网站的地址
     */
    @Value(value = "${alipay.h5Pay.quitUrl:}")
    private String h5PayQuitUrl;

    /**
     * 实例化客户端
     */
    private DefaultAlipayClient client;

    @Value("${spring.profiles.active:}")
    private String profiles;

    private final ResourceLoader resourceLoader;

    public AliPayClient(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public Integer getType() {
        return EPayChannel.ALIPAY.getType();
    }

    /**
     * 初始化支付宝client对象
     */
    @PostConstruct
    public void initPostConstruct() {
        client = this.getCertClient();
    }

    /**
     * https://opendocs.alipay.com/apis/api_28/alipay.fund.trans.uni.transfer
     *
     * @param baseTransferRequest 打款请求参数
     * @param <V> 响应实体
     * @return 响应信息
     */
    @Override
    public <V extends BaseTransferResponse> V transfer(BaseTransferRequest<V> baseTransferRequest) {
        if (!(baseTransferRequest instanceof AliPayTransferRequest)) {
            throw new BusinessException("支付宝转账参数对象发送错误:" + baseTransferRequest.getClass());
        }
        AliPayTransferRequest transferRequest = (AliPayTransferRequest) baseTransferRequest;
        AliPayTransferContentDTO aliPayTransferContentDTO = new AliPayTransferContentDTO();
        aliPayTransferContentDTO.setRemark(transferRequest.getRemark());
        aliPayTransferContentDTO.setOutBizNo(transferRequest.getOrderNo());
        aliPayTransferContentDTO.setAmount(transferRequest.getAmount().toString());
        aliPayTransferContentDTO.setProductCode("TRANS_ACCOUNT_NO_PWD");
        aliPayTransferContentDTO.setBizScene("DIRECT_TRANSFER");
        aliPayTransferContentDTO.setOrderTitle(transferRequest.getOrderTitle());
        AliPayTransferContentDTO.Participant participantRequest = new AliPayTransferContentDTO.Participant();
        // 收款方打款方式 1、会员ID 2、支付宝登录号
        if (transferRequest.getIdentityType() == 1) {
            participantRequest.setIdentity(transferRequest.getAliPayUserId());
            participantRequest.setIdentityType("ALIPAY_USER_ID");
        } else {
            participantRequest.setIdentityType("ALIPAY_LOGON_ID");
            participantRequest.setIdentity(transferRequest.getWithdrawAccount());
            participantRequest.setName(transferRequest.getName());
        }

        aliPayTransferContentDTO.setParticipant(participantRequest);
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        request.setBizContent(JsonUtils.toJSONString(aliPayTransferContentDTO));

        DefaultAlipayClient DefaultAlipayClient = this.getCertClient();
        try {
            log.info("支付宝转账请求参数：" + JsonUtils.toJSONString(request));
            AlipayFundTransUniTransferResponse transferResponse = DefaultAlipayClient.certificateExecute(request);
            log.info("支付宝转账返回内容：" + JsonUtils.toJSONString(transferResponse));

            AliPayTransferResponse response = new AliPayTransferResponse();
            response.setOutTradeNo(transferResponse.getOutBizNo());
            response.setChannelFundOrderNo(transferResponse.getPayFundOrderId());
            response.setChannelOrderNo(transferResponse.getOrderId());
            response.setAppId(appId);
            if (StringUtils.isNotBlank(transferResponse.getTransDate())) {
                response.setFinishTime(DateUtils.strToDate(transferResponse.getTransDate()));
            }
            if (!transferResponse.isSuccess()) {
                response.setStatus(EPayOrderStatus.FAIL);
                if ("BALANCE_IS_NOT_ENOUGH".equals(transferResponse.getSubCode())) {
                    response.setErrorMsg("系统账户余额已提现完毕，待平台充值后再操作");
                } else {
                    response.setErrorMsg(transferResponse.getSubMsg());
                }
            } else {
                response.setStatus(EPayOrderStatus.SUCCESS);
            }
            return (V) response;
        } catch (AlipayApiException e) {
            log.error("调用支付宝转账接口发生异常", e);
            throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
        }
    }

    /**
     * https://opendocs.alipay.com/apis/api_2/alipay.user.info.share
     * @param request 请求参数实体
     * @param <T>
     * @return
     */
    @Override
    public <T extends BaseQueryUserInfoResponse> T getUserInfo(BaseQueryUserInfoRequest<T> request) {
        if (!(request instanceof AliPayQueryUserInfoRequest)) {
            throw new BusinessException("获取支付宝用户信息参数对象发送错误:" + request.getClass());
        }
        AliPayQueryUserInfoRequest queryUserInfoRequest = (AliPayQueryUserInfoRequest) request;

        DefaultAlipayClient DefaultAlipayClient = this.getCertClient();

        AlipayUserInfoShareRequest alipayUserInfoShareRequest = new AlipayUserInfoShareRequest();
        try {
            log.info("支付宝获取用户信息请求参数：" + JsonUtils.toJSONString(queryUserInfoRequest));
            AlipayUserInfoShareResponse userInfoShareResponse = DefaultAlipayClient.certificateExecute(alipayUserInfoShareRequest, queryUserInfoRequest.getAuthToken());
            log.info("支付宝获取用户信息返回内容：" + JsonUtils.toJSONString(userInfoShareResponse));
            if (userInfoShareResponse.isSuccess()) {
                AliPayQueryUserInfoResponse response = new AliPayQueryUserInfoResponse();
                response.setAppId(appId);
                response.setAliPayUserId(userInfoShareResponse.getUserId());
                response.setNickName(userInfoShareResponse.getNickName());
                response.setAvatar(userInfoShareResponse.getAvatar());
                return (T) response;
            } else {
                throw new BusinessException(userInfoShareResponse.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("调用支付宝查询用户信息接口发生异常", e);
            throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
        }
    }

    /**
     * https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay?scene=20
     * @param request 请求参数
     * @return 订单信息
     */
    @Override
    public <T extends BasePreOrderResponse> T appPreOrder(BasePreOrderRequest<T> request) {
        if (!(request instanceof AliPayAppPreOrderRequest)) {
            throw new BusinessException("创建支付宝预订单参数对象发送错误:" + request.getClass());
        }
        AliPayAppPreOrderRequest aliPayAppPreOrderRequest = (AliPayAppPreOrderRequest)request;
        AlipayTradeAppPayRequest alipayTradeAppPayRequest = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(aliPayAppPreOrderRequest.getBody());
        model.setSubject(aliPayAppPreOrderRequest.getSubject());
        model.setOutTradeNo(aliPayAppPreOrderRequest.getOutTradeNo());
        model.setTimeoutExpress(aliPayAppPreOrderRequest.getTimeoutExpress());
        model.setTimeExpire(aliPayAppPreOrderRequest.getTimeExpire());
        model.setTotalAmount(aliPayAppPreOrderRequest.getTotalAmount());
        model.setProductCode("QUICK_MSECURITY_PAY");
        alipayTradeAppPayRequest.setBizModel(model);
        alipayTradeAppPayRequest.setNotifyUrl(appPayCallbackUrl + "/"  + appId);
        try {
            //这里和普通的接口调用不同，使用的是execute
            log.info("支付宝创建预订单请求参数:{}", JsonUtils.toJSONString(alipayTradeAppPayRequest));
            AlipayTradeAppPayResponse alipayTradeAppPayResponse = client.execute(alipayTradeAppPayRequest);
            log.info("支付宝创建预订单响应参数:{}", JsonUtils.toJSONString(alipayTradeAppPayResponse));
            AliPayAppPreOrderResponse response = new AliPayAppPreOrderResponse();
            response.setBody(alipayTradeAppPayResponse.getBody());
            response.setAppId(appId);
            return (T) response;
        } catch (AlipayApiException e) {
            log.error("调用支付宝创建预订单接口发生异常", e);
            throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
        }
    }

    /**
     * https://opendocs.alipay.com/open/02ivbs?scene=21&pathHash=0a6313c7
     *
     * @param request 请求参数
     * @param <T>
     * @return
     */
    @Override
    public <T extends BasePreOrderResponse> T h5PreOrder(BasePreOrderRequest<T> request) {
        if (!(request instanceof AliPayH5PreOrderRequest)) {
            throw new BusinessException("创建支付宝预订单参数对象发送错误:" + request.getClass());
        }
        AliPayH5PreOrderRequest appH5PreOrderRequest = (AliPayH5PreOrderRequest)request;

        /* 实例化具体API对应的request类，类名称和接口名称对应，当前调用接口名称：alipay.trade.wap.pay（手机网站支付） **/
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        /* 设置业务参数  **/
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        /* 商户订单号，商户自定义，需保证在商户端不重复，如：20200612000001 **/
        model.setOutTradeNo(appH5PreOrderRequest.getOutTradeNo());
        /* 销售产品码，固定值：QUICK_WAP_WAY **/
        model.setProductCode("QUICK_WAP_WAY");
        /* 订单标题 **/
        model.setSubject(appH5PreOrderRequest.getSubject());
        /* 订单金额，精确到小数点后两位 **/
        model.setTotalAmount(appH5PreOrderRequest.getTotalAmount());
        // 添加该参数后在h5支付收银台会出现返回按钮，可用于用户付款中途退出并返回到该参数指定的商户网站地址。
        model.setQuitUrl(h5PayQuitUrl);
        /* 订单描述 **/
        model.setBody(appH5PreOrderRequest.getBody());
        /* 业务扩展参数 **/
        //ExtendParams extendParams = new ExtendParams();
        /** 系统商编号，填写服务商的PID，返佣参数传值前提：传值账号需要签约返佣协议，用于isv商户。 **/
        //extendParams.setSysServiceProviderId("2088511****07846");
        /** 花呗分期参数，传值前提：必须有该接口花呗收款准入条件，且需签约花呗分期 **/
        /** 指定可选期数，只支持3/6/12期，还款期数越长手续费越高 **/
        // extendParams.setHbFqNum("3");
        /** 指定花呗分期手续费承担方式，手续费可以由用户全承担（该值为0），也可以商户全承担（该值为100），但不可以共同承担，即不可取0和100外的其他值。 **/
        //extendParams.setHbFqSellerPercent("0");
        //model.setExtendParams(extendParams);
        /** 将业务参数传至request中 **/
        alipayRequest.setBizModel(model);
        /** 注：支付结果以异步通知为准，不能以同步返回为准，因为如果实际支付成功，但因为外力因素，如断网、断电等导致页面没有跳转，则无法接收到同步通知；**/
        /** 同步通知地址，以http或者https开头，支付完成后跳转的地址，用于用户视觉感知支付已成功，传值外网可以访问的地址，如果同步未跳转可参考该文档进行确认：https://opensupport.alipay.com/support/helpcenter/193/201602474937 **/
        alipayRequest.setReturnUrl(appH5PreOrderRequest.getReturnUrl());

        /** 异步通知地址，以http或者https开头的，商户外网可以post访问的异步地址，用于接收支付宝返回的支付结果，如果未收到该通知可参考该文档进行确认：https://opensupport.alipay.com/support/helpcenter/193/201602475759 **/
        alipayRequest.setNotifyUrl(appPayCallbackUrl + "/" + appId);

        /**第三方调用（服务商模式），传值app_auth_token后，会收款至授权app_auth_token对应商家账号，如何获传值app_auth_token请参考文档：https://opensupport.alipay.com/support/helpcenter/79/201602494631 **/
        //request.putOtherTextParam("app_auth_token", "传入获取到的app_auth_token值");

        String form = null;
        try {

            /** 调用SDK生成表单form表单 **/
            log.info("支付宝创建h5预订单请求参数:{}", JsonUtils.toJSONString(alipayRequest));
            AlipayTradeWapPayResponse alipayTradeWapPayResponse = client.pageExecute(alipayRequest);
            log.info("支付宝创建h5预订单响应参数:{}", alipayTradeWapPayResponse);
            form = alipayTradeWapPayResponse.getBody();

        } catch (AlipayApiException e) {
           log.error("支付宝h5网站预订单生成失败", e);
           throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
        }
        AliPayH5PreOrderResponse response = new AliPayH5PreOrderResponse();
        response.setBody(form);
        response.setAppId(appId);
        return (T) response;
    }

    @Override
    public <T extends BaseQueryOrderResponse> T queryOrder(BaseQueryOrderRequest<T> request) {
        if (!(request instanceof AliPayQueryOrderRequest)) {
            throw new BusinessException("请求参数实体错误");
        }
        AliPayQueryOrderRequest queryOrderRequest = (AliPayQueryOrderRequest)request;
        // 封装请求参数
        AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", queryOrderRequest.getOutTradeNo());
        bizContent.put("trade_no", queryOrderRequest.getTradeNo());
        alipayTradeQueryRequest.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = null;
        try {
            response = client.certificateExecute(alipayTradeQueryRequest);
            if(response.isSuccess()){
                return (T) BeansUtils.map(response, AliPayQueryOrderResponse.class);
            }
            throw new BusinessException(response.getSubMsg());
        } catch (AlipayApiException e) {
            log.error("查询订单失败", e);
        }
        throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
    }

    /**
     * 验签V1版本
     * @param params 请求参数
     * @return 验签结果
     */
    public boolean rsaCheckV1(Map<String, String> params, String appId) {
        try {
            return AlipaySignature.rsaCertCheckV1(params, publicCertPath, "UTF-8", AlipayConstants.SIGN_TYPE_RSA2);
        } catch (AlipayApiException e) {
            log.error("支付宝验签失败", e);
            return false;
        }
    }

    @Override
    public <T extends BaseOauthTokenResponse> T oauthToken(BaseOauthTokenRequest<T> request) {
        if (!(request instanceof AliPayOauthTokenRequest)) {
            throw new BusinessException("请求参数实体错误");
        }
        AliPayOauthTokenRequest aliPayOauthTokenRequest = (AliPayOauthTokenRequest)request;
        AlipaySystemOauthTokenRequest systemOauthTokenRequest = new AlipaySystemOauthTokenRequest();
        if (aliPayOauthTokenRequest.getGrantType() == 1) {
            systemOauthTokenRequest.setGrantType("authorization_code");
            systemOauthTokenRequest.setCode(aliPayOauthTokenRequest.getCode());
        } else {
            systemOauthTokenRequest.setGrantType("refresh_token");
            systemOauthTokenRequest.setRefreshToken(aliPayOauthTokenRequest.getRefreshToken());
        }

        DefaultAlipayClient DefaultAlipayClient = this.getCertClient();
        try {
            AlipaySystemOauthTokenResponse response = DefaultAlipayClient.certificateExecute(systemOauthTokenRequest);
            if (response.isSuccess()) {
                AliPayOauthTokenResponse aliPayOauthTokenResponse = new AliPayOauthTokenResponse();
                aliPayOauthTokenResponse.setAccessToken(response.getAccessToken());
                aliPayOauthTokenResponse.setChannelUserId(response.getUserId());
                aliPayOauthTokenResponse.setExpiresIn(response.getExpiresIn());
                aliPayOauthTokenResponse.setReExpiresIn(response.getReExpiresIn());
                aliPayOauthTokenResponse.setRefreshToken(response.getRefreshToken());
                return (T) aliPayOauthTokenResponse;
            } else {
                throw new BusinessException(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("获取用户授权码失败", e);
        }
        throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);

    }

    /**
     * https://opendocs.alipay.com/open/02ivbx?pathHash=d98b006d#4%20%E5%93%8D%E5%BA%94%E5%8F%82%E6%95%B0
     * @param request 请求参数
     * @return 返回信息
     */
    @Override
    public <T extends BaseRefundResponse> T refund(BaseRefundRequest<T> request) {
        if (!(request instanceof AliPayRefundRequest)) {
            throw new BusinessException("请求参数实体错误");
        }
        AliPayRefundRequest refundRequest = (AliPayRefundRequest) request;
        AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setTradeNo(refundRequest.getTradeNo());
        model.setOutTradeNo(refundRequest.getOutTradeNo());
        model.setRefundAmount(refundRequest.getRefundAmount());
        model.setRefundReason(refundRequest.getRefundReason());
        model.setOutRequestNo(refundRequest.getOutRequestNo());
        alipayTradeRefundRequest.setBizModel(model);
        // 获取对应的client，由于退款是低频操作，暂时不对历史appId的client进行缓存
        try {
            log.info("支付宝退款请求参数：" + JsonUtils.toJSONString(alipayTradeRefundRequest));
            AlipayTradeRefundResponse response = client.certificateExecute(alipayTradeRefundRequest);
            log.info("支付宝退款响应结果：" + JsonUtils.toJSONString(response));
            if (response.isSuccess()) {
                AliPayRefundResponse refundResponse = BeansUtils.map(response, AliPayRefundResponse.class);
                return (T) refundResponse;
            } else {
                throw new BusinessException(response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            log.error("获取用户授权码失败", e);
        }
        throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
    }

    /**
     * 初始化client
     *
     */
    private DefaultAlipayClient getCertClient() {
        //请求和签名使用的字符编码格式，支持 GBK和 UTF-8
        String charset = "UTF-8";
        //商户生成签名字符串所使用的签名算法类型，目前支持RSA2和RSA，推荐使用RSA2
        String signType = "RSA2";
        //仅支持JSON
        String format = "JSON";
//        String serverUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
        String serverUrl = "https://openapi.alipay.com/gateway.do";
        // 公钥证书方式配置，调用使用client.certificateExecute方法
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        //gateway:支付宝网关（固定）https://openapi.alipay.com/gateway.do
        certAlipayRequest.setServerUrl(serverUrl);
        //参数返回格式，只支持 json 格式
        certAlipayRequest.setFormat(format);
        //请求和签名使用的字符编码格式，支持 GBK和 UTF-8
        certAlipayRequest.setCharset(charset);
        //商户生成签名字符串所使用的签名算法类型，目前支持 RSA2 和 RSA，推荐商家使用 RSA2。
        certAlipayRequest.setSignType(signType);
        //APPID 即创建应用后生成,详情见创建应用并获取 APPID
        certAlipayRequest.setAppId(appId);
        // 开发者应用私钥，由开发者自己生成
        certAlipayRequest.setPrivateKey(privateKey);
        try {
            String appCertContent = IoUtil.read(resourceLoader.getResource("classpath:" + appCertPath).getInputStream(), "utf-8");
            //应用公钥证书路径（app_cert_path 文件绝对路径）
            certAlipayRequest.setCertContent(appCertContent);
            //支付宝公钥证书文件路径（alipay_cert_path 文件绝对路径）
            String publicCertContent = IoUtil.read(resourceLoader.getResource("classpath:" + publicCertPath).getInputStream(), "utf-8");
            certAlipayRequest.setAlipayPublicCertContent(publicCertContent);
            //支付宝CA根证书文件路径（alipay_root_cert_path 文件绝对路径）
            String rootCertContent = IoUtil.read(resourceLoader.getResource("classpath:" + rootCertPath).getInputStream(), "utf-8");
            certAlipayRequest.setRootCertContent(rootCertContent);
            log.info(profiles + ":初始化支付宝客户端...");
            return new DefaultAlipayClient(certAlipayRequest);
        } catch (Exception e) {
            throw new BusinessException("支付宝客户端初始化失败", e);
        }
    }

    //
//    /**
//     * https://opendocs.alipay.com/apis/api_28/alipay.fund.trans.common.query
//     *
//     * @param remitQueryRequest
//     * @param <V>
//     * @return
//     */
//    @Override
//    public <V extends ClientBaseRemitQueryResponse> V remitQuery(ClientBaseRemitQueryRequest<V> remitQueryRequest) {
//        if (!(remitQueryRequest instanceof AliPayTransferQueryRequest)) {
//            throw new BusinessException("支付宝查询转账参数对象发送错误:" + remitQueryRequest.getClass());
//        }
//        AliPayTransferQueryRequest queryRequest = (AliPayTransferQueryRequest) remitQueryRequest;
//        AliPayTransferQueryContentDTO queryDto = new AliPayTransferQueryContentDTO();
//        queryDto.setBizScene("DIRECT_TRANSFER");
//        queryDto.setOrderId(queryRequest.getPlatOrderNo());
//        queryDto.setOutBizNo(queryRequest.getOrderId());
//        queryDto.setPayFundOrderId(queryRequest.getPayOrderNumber());
//        queryDto.setProductCode("TRANS_ACCOUNT_NO_PWD");
//        AlipayFundTransCommonQueryRequest request = new AlipayFundTransCommonQueryRequest();
//        request.setBizContent(JsonUtils.toJSONString(queryDto));
//        AliPayTransferQueryResponse response = null;
//        WithdrawPlatformDTO config = appPlatformManagerService.getConfigByAppId(queryRequest.getAppId(), PlatformType.ALIPAY.getType());
//        if (config == null) {
//            throw new BusinessException(WithdrawOrderCode.NO_WITHDRAW_TYPE);
//        }
//        AlipayClient client = this.getClient(config.getId());
//        try {
//            AlipayFundTransCommonQueryResponse queryResponse = client.execute(request);
//            response = new AliPayTransferQueryResponse();
//            response.setPlatOrderId(queryResponse.getOrderId());
//            response.setOrderId(queryResponse.getOutBizNo());
//            response.setPayDate(queryResponse.getPayDate());
//            response.setPayFundOrderId(queryResponse.getPayFundOrderId());
//            response.setTransAmount(queryResponse.getTransAmount());
//            // SUCCESS：转账成功、FAIL：失败（适用于"单笔转账到银行卡"）、DEALING：处理中（适用于"单笔转账到银行卡"）、REFUND：退票（适用于"单笔转账到银行卡"）
//            // todo: 支付宝转账用不上查询，后续接入银行卡需要将状态这一块补上
//            if (queryResponse.isSuccess()) {
//                System.out.println("调用成功");
//            } else {
//                System.out.println("调用失败");
//            }
//        } catch (AlipayApiException e) {
//            asyncManagerService.sendDingTalkAsync(DingTalkConstant.ALIPAY_ERROR, "调用支付宝转账订单查询接口发生异常:" + e.getMessage());
//            log.error("调用支付宝查询转账记录接口发生异常", e);
//        }
//        return (V) response;
//    }
//
//    /**
//     * 查询余额
//     * https://opendocs.alipay.com/apis/api_28/alipay.fund.account.query
//     * @param request 请求参数
//     * @param <V> 返回数据类型
//     * @return 余额信息
//     */
//    @Override
//    public <V extends ClientBaseBalanceQueryResponse> V balanceQuery(ClientBaseBalanceQueryRequest<V> request) {
//        if (!(request instanceof AliPayQueryBalanceRequest)) {
//            throw new BusinessException("支付宝查询余额参数对象发送错误:" + request.getClass());
//        }
//        WithdrawPlatformDTO config = appPlatformManagerService.getConfigByCompanyId(request.getCompanyId(), PlatformType.ALIPAY.getType());
//        if (config == null) {
//            throw new BusinessException(WithdrawOrderCode.NO_WITHDRAW_TYPE);
//        }
//        // 封装请求实体
//        AlipayFundAccountQueryRequest alipayFundAccountQueryRequest = new AlipayFundAccountQueryRequest();
//        AliPayQueryBalanceDTO aliPayQueryBalanceDTO = new AliPayQueryBalanceDTO();
//        aliPayQueryBalanceDTO.setAccountType("ACCTRANS_ACCOUNT");
//        aliPayQueryBalanceDTO.setAlipayUserId(config.getAlipayUserId());
//        alipayFundAccountQueryRequest.setBizContent(JsonUtils.toJSONString(aliPayQueryBalanceDTO));
//
//        // 请求并封装返回实体
//        try {
//            AlipayClient client = this.getClient(config.getId());
//            AlipayFundAccountQueryResponse response = client.execute(alipayFundAccountQueryRequest);
//            if (response.isSuccess()) {
//                AliPayQueryBalanceResponse queryBalanceResponse = new AliPayQueryBalanceResponse();
//                queryBalanceResponse.setBalance(new BigDecimal(response.getAvailableAmount()));
//                queryBalanceResponse.setPlatId(config.getId());
//                return (V) queryBalanceResponse;
//            } else {
//                log.error("调用支付宝查询余额接口异常：{}", JsonUtils.toJSONString(response));
//                throw new BusinessException(response.getSubCode());
//            }
//        } catch (AlipayApiException e) {
//            asyncManagerService.sendDingTalkAsync(DingTalkConstant.ALIPAY_ERROR, "调用支付宝查询余额接口发生异常:" + e.getMessage());
//            log.error("调用支付宝查询余额接口发生异常", e);
//        }
//        return null;
//    }
}
